/**
 * 
 */
package com.fitbet.api.web.controller.resolver;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.fitbet.api.Constant;
import com.fitbet.api.service.UserService;
import com.fitbet.entity.user.User;

/**
 * 
 * @author lute
 *
 */
public class SecurityArgumentResolver implements HandlerMethodArgumentResolver {

    private static final Logger logger = LoggerFactory.getLogger(SecurityArgumentResolver.class);
    
    private String unionidKey = Constant.UNIONID_KEY;
    
    @Autowired
    private UserService userService;
    
    /**
     * @param unionidKey
     */
    public void setUnionidKey(String unionidKey) {
        this.unionidKey = unionidKey;
    }
    
    /* (non-Javadoc)
     * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
     */
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Secure.class);
    }

    /* (non-Javadoc)
     * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.method.support.ModelAndViewContainer, org.springframework.web.context.request.NativeWebRequest, org.springframework.web.bind.support.WebDataBinderFactory)
     */
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        
        Secure secure = parameter.getParameterAnnotation(Secure.class);
        
        if (StringUtils.isNotBlank(secure.value())) {
            this.unionidKey = secure.value();
        }
        
        logger.trace("#resolveArgument() - Get unionid key [{}].", unionidKey);
        
        // Transform NativeWebRequest to HttpServletRequest
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        
        // Get unionid cookie
        String unionid = request.getParameter(unionidKey);
        
        logger.trace("#resolveArgument() - Get unionid cookie by unionidKey [{}].", unionidKey);
        
        if (unionid != null) {
            
            
            logger.trace("#resolveArgument() - Get unionid cookie success ======== UNIONID COOKIE VALUE IS [{}].", unionid);
            
            // Load user
            User user = userService.loadUser(unionid);
            
            // Return user when there's no property in secure annotation
            if (user != null && parameter.getParameterType().isAssignableFrom(user.getClass())) {
                logger.trace("#resolveArgument() - Load user by unionid [{}] and user id is [{}].", unionid, user.getId());
                return user;
            }
            
            logger.trace("#resolveArgument() - Load user by unionid [{}] failed.", unionid);
            
        }else {
            
            logger.trace("#resolveArgument() - Get unionid cookie failed ======== MOBILE UNIONID NOT EXIT.");
        }
        
        return null;
    }

}
